﻿using System;

namespace Qy.Core;

/// <summary>
///  时间格式化转换
/// </summary>
public static class DateUtility
{
    /// <summary>
    /// 
    /// </summary>
    /// <param name="dateTime"></param>
    /// <returns></returns>
    public static DateTime GetBeginTime(DateTime? dateTime, int days = 0)
    {
        if (dateTime == DateTime.MinValue || dateTime == null)
        {
            return DateTime.Now.AddDays(days);
        }
        return dateTime ?? DateTime.Now;
    }

    /// <summary>
    /// 获取时期天起始时间
    /// </summary>
    /// <param name="dateTime"></param>
    /// <returns></returns>
    public static DateTime GetDayBeginTime(this DateTime? dateTime)
    {
        if (!dateTime.HasValue)
            return DateTime.Now.Date;
        return GetDayBeginTime(dateTime.Value);
    }

    /// <summary>
    /// 获取时期天起始时间
    /// </summary>
    /// <param name="dateTime"></param>
    /// <returns></returns>
    public static DateTime GetDayBeginTime(this DateTime dateTime)
    {
        return dateTime.Date;
    }

    /// <summary>
    /// 获取时期天的结束时间
    /// </summary>
    /// <param name="dateTime"></param>
    /// <returns></returns>
    public static DateTime GetDayEndTime(this DateTime? dateTime)
    {
        if (!dateTime.HasValue)
            return DateTime.Now;
        return GetDayEndTime(dateTime.Value);
    }

    /// <summary>
    /// 获取时期天的结束时间
    /// </summary>
    /// <param name="dateTime"></param>
    /// <returns></returns>
    public static DateTime GetDayEndTime(this DateTime dateTime)
    {
        return new DateTime(dateTime.Year, dateTime.Month, dateTime.Day, 23, 59, 59);
    }

    /// <summary>
    /// 与当前时间差值(分钟)
    /// </summary>
    /// <param name="dateTime"></param>
    /// <returns></returns>
    public static int WithDiffMinutes(this DateTime? dateTime)
    {
        if (!dateTime.HasValue)
            return 0;
        return WithDiffMinutes(dateTime.Value);
    }

    /// <summary>
    /// 与当前时间差值(分钟)
    /// </summary>
    /// <param name="dateTime"></param>
    /// <returns></returns>
    public static int WithDiffMinutes(this DateTime dateTime)
    {
        //if (dateTime == null) return 0;
        TimeSpan ts1 = new(dateTime.Ticks);
        TimeSpan ts2 = new(DateTime.Now.Ticks);
        TimeSpan ts = ts1.Subtract(ts2).Duration();
        return (int)ts.TotalMinutes;
    }

    /// <summary>
    /// 转换到剩余时间
    /// </summary>
    /// <param name="deadline"></param>
    /// <returns></returns>
    public static string ToTimeLeft(this DateTime? deadline)
    {
        if (!deadline.HasValue) return "N/A";
        return (deadline.Value).ToTimeLeft();
    }

    /// <summary>
    /// 转换到剩余时间
    /// </summary>
    /// <param name="deadline"></param>
    /// <returns></returns>
    public static string ToTimeLeft(this DateTime deadline)
    {
        //if (deadline == null) return "N/A";
        int totalSeconds = (int)deadline.Subtract(DateTime.Now).TotalSeconds;
        TimeSpan ts = new(0, 0, totalSeconds);
        if (ts.Days > 0)
        {
            return ts.Days.ToString() + "天";
        }
        if (ts.Days == 0 && ts.Hours > 0)
        {
            return ts.Hours.ToString() + "小时 ";
        }
        if (ts.Days == 0 && ts.Hours == 0 && ts.Minutes > 0)
        {
            return ts.Minutes.ToString() + "分钟 ";
        }
        return "N/A";
    }

    /// <summary>
    /// 格式化为(月/日)
    /// </summary>
    /// <param name="dateTime"></param>
    /// <returns></returns>
    public static string ToMonthDayFormat(this DateTime? dateTime)
    {
        if (dateTime.HasValue)
            return dateTime.Value.ToMonthDayFormat();
        else
            return "N/A";
    }

    /// <summary>
    /// 格式化为(月/日)
    /// </summary>
    /// <param name="dateTime"></param>
    /// <returns></returns>
    public static string ToMonthDayFormat(this DateTime dateTime)
    {
        return dateTime.ToString("MM/dd");
    }

    /// <summary>
    /// 标准格式(yyyy-MM-dd hh:mm:ss)
    /// </summary>
    /// <param name="dateTime"></param>
    /// <param name="defaultValue"></param>
    /// <returns></returns>
    public static string ToStandardFormat(this DateTime? dateTime, string defaultValue = "N/A")
    {
        if (dateTime.HasValue)
            return dateTime.Value.ToStandardFormat();
        else
            return defaultValue;
    }


    /// <summary>
    /// 标准格式(yyyy-MM-dd hh:mm:ss)
    /// </summary>
    /// <param name="dateTime"></param>
    /// <returns></returns>
    public static string ToStandardFormat(this DateTime dateTime)
    {
        return dateTime.ToString("yyyy-M-dd HH:mm");
    }

    /// <summary>
    /// 转换为日期
    /// </summary>
    /// <param name="dateTime"></param>
    /// <returns></returns>
    public static string ToDateFormat(this DateTime dateTime)
    {
        return dateTime.ToString("yyyy-MM-dd");
    }

    /// <summary>
    /// 智能时间提示(yyyy-MM-dd hh:mm 和 刚刚)
    /// </summary>
    /// <param name="dateTime"></param>
    /// <returns></returns>
    public static string ToSmartFormat(this DateTime? dateTime)
    {
        if (dateTime.HasValue)
            return dateTime.Value.ToSmartFormat();
        else
            return "N/A";
    }

    /// <summary>
    /// 智能时间提示(yyyy-MM-dd hh:mm 和 刚刚)
    /// </summary>
    /// <param name="dateTime"></param>
    /// <returns></returns>
    public static string ToSmartFormat(this DateTime dateTime)
    {
        DateTime date1 = DateTime.Now;
        DateTime date2 = dateTime;
        TimeSpan dt = date1 - date2;

        // 相差天数
        int days = dt.Days;
        // 时间点相差小时数
        int hours = dt.Hours;
        // 相差总小时数
        double Minutes = dt.Minutes;
        // 相差总秒数
        // int second = dt.Seconds;

        string strTime;
        if (days == 0 && hours == 0 && Minutes == 0)
        {
            strTime = "刚刚";
        }
        else if (days == 0 && hours == 0)
        {
            strTime = Minutes + "分钟前";
        }
        else if (days == 0)
        {
            strTime = hours + "小时前";
        }
        else
        {
            strTime = dateTime.ToString("yyyy-M-dd HH:mm");
        }
        return strTime;
    }

    /// <summary>
    /// 转换为时期数字格式(例如:20180324)
    /// </summary>
    /// <param name="dateTime"></param>
    /// <returns></returns>
    public static int ToDateNumber(this DateTime dateTime)
    {
        return dateTime.Year * 10000 + dateTime.Month * 100 + dateTime.Day;
    }

    public static string ShowNotAvailable(this DateTime? dateTime)
    {
        if (!dateTime.HasValue)
            return "N/A";

        return dateTime.Value.ToSmartFormat();
    }

    /// <summary>
    /// 日期转换为时间戳（时间戳单位秒）
    /// </summary>
    /// <param name="dateTime"></param>
    /// <returns></returns>
    public static long ToTimeStamp(this DateTime dateTime)
    {
        DateTime Jan1st1970 = new(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc);
        return (long)(dateTime.AddHours(-8) - Jan1st1970).TotalMilliseconds;
    }

    /// <summary>
    /// 时间戳转时间  微秒
    /// </summary>
    /// <param name="timeStamp"></param>
    /// <returns></returns>
    public static DateTime ToDateTime(this long timeStamp)
    {
        DateTime Jan1st1970 = new(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc);
        return Jan1st1970.AddHours(8).AddMilliseconds(timeStamp);
    }

    /// <summary>
    /// 时间戳转时间 10位 秒级
    /// </summary>
    /// <param name="timeStamp"></param>
    /// <returns></returns>
    public static DateTime ToDateTime10(this long timeStamp)
    {
        DateTime Jan1st1970 = new(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc);
        return Jan1st1970.AddHours(8).AddSeconds(timeStamp);
    }

    public static long ToTimeNumber(this DateTime dateTime)
    {
        string dateStr = dateTime.ToString("yyyyMMdH");
        return long.Parse(dateStr);
    }

    public static long ToNumber(this DateTime dateTime)
    {
        string dateStr = dateTime.ToString("yyyyMMddHH");
        return long.Parse(dateStr);
    }


    /// <summary>
    /// 毫秒转天时分秒
    /// </summary>
    /// <param name="ms"></param>
    /// <returns></returns>
    public static string FormatTime(long ms)
    {
        int ss = 1000;
        int mi = ss * 60;
        int hh = mi * 60;
        int dd = hh * 24;

        long day = ms / dd;
        long hour = (ms - day * dd) / hh;
        long minute = (ms - day * dd - hour * hh) / mi;
        long second = (ms - day * dd - hour * hh - minute * mi) / ss;
       // long milliSecond = ms - day * dd - hour * hh - minute * mi - second * ss;

        string sDay = day < 10 ? "0" + day : "" + day; //天
        string sHour = hour < 10 ? "0" + hour : "" + hour;//小时
        string sMinute = minute < 10 ? "0" + minute : "" + minute;//分钟
        string sSecond = second < 10 ? "0" + second : "" + second;//秒
       // string sMilliSecond = milliSecond < 10 ? "0" + milliSecond : "" + milliSecond;//毫秒
        //sMilliSecond = milliSecond < 100 ? "0" + sMilliSecond : "" + sMilliSecond;

        return string.Format("{0} 天 {1} 小时 {2} 分 {3} 秒", sDay, sHour, sMinute, sSecond);
    }
}
